package com.allenkerr;

import java.util.List;
import java.util.Random;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.*;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.CollectionUtils;

import com.allenkerr.queue1.RedisQueue1;
import com.allenkerr.queue1.RedisTaskContainer;
import com.allenkerr.model.Person;
import com.allenkerr.queue3.RedisQueue3;

@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisTest1 {

  @Autowired
  private StringRedisTemplate stringRedisTemplate;

  @Autowired
  private RedisTemplate redisTemplate;

  @Test
  public void test1() {
    //保存字符串
    stringRedisTemplate.opsForValue().set("str1", "abcdefg");
    //断言
    Assert.assertEquals("abcdefg", stringRedisTemplate.opsForValue().get("str1"));
  }

  @Test
  public void test2() {
    String str1 = stringRedisTemplate.opsForValue().get("str1");
    System.out.println(str1);
  }

  /**
   * 使用 Redis 保存对象
   */
  @Test
  public void test3() {
    final ValueOperations<String, Person> opsForValue = redisTemplate.opsForValue();

    Person p1 = new Person("Super Man", "123456", "超人");
    Person p2 = new Person("Bat Man", "abcdefg", "蝙蝠侠");
    Person p3 = new Person("Magic Woman", "098765", "神奇女侠");

    opsForValue.set(p1.getUsername(), p1);
    opsForValue.set(p2.getUsername(), p2);
    opsForValue.set(p3.getUsername(), p3);

    Person p1InRedis = opsForValue.get(p1.getUsername());
    System.out.println("p1InRedis = " + p1InRedis);
  }

  /**
   * 使用 Redis 保存对象到 hash 中去
   */
  @Test
  public void test4() {
    final HashOperations<String, String, Person> opsForHash = redisTemplate.opsForHash();

    Person p1 = new Person("Super Man", "123456", "超人");
    Person p2 = new Person("Bat Man", "abcdefg", "蝙蝠侠");
    Person p3 = new Person("Magic Woman", "098765", "神奇女侠");

    String hashName = "Person";
    opsForHash.put(hashName, p1.getUsername(), p1);
    opsForHash.put(hashName, p2.getUsername(), p2);
    opsForHash.put(hashName, p3.getUsername(), p3);

    Person person = (Person) opsForHash.get(hashName, p1.getUsername());
    System.out.println("person = " + person);
  }

  /**
   * 使用 Redis 保存对象到 list 中去
   */
  @Test
  public void test5() {
    final ListOperations<String, Person> opsForList = redisTemplate.opsForList();

    Person p1 = new Person("Super Man", "123456", "超人");
    Person p2 = new Person("Bat Man", "abcdefg", "蝙蝠侠");
    Person p3 = new Person("Magic Woman", "098765", "神奇女侠");

    String listName = "PersonList";
    Long aLong = opsForList.leftPushAll(listName, p1, p2, p3);
    System.out.println("aLong = " + aLong);

    List<Person> personList = opsForList.range(listName, 0, -1);
    personList.forEach(System.out::println);
  }

  /**
   * 使用 Redis 队列作为后台任务处理队列
   */
  @Test
  public void test6() throws InterruptedException {
    final ListOperations<String, Integer> opsForList = redisTemplate.opsForList();
    opsForList.leftPushAll(RedisTaskContainer.ORDER_ID_QUEUE, 1, 2, 3, 4, 5, 6, 7);

    final Random random = new Random();

    while (true) {
      Thread.sleep(2000);
      int num = random.nextInt(50);
      System.out.println(num);
//      opsForList.leftPush(RedisTaskContainer.ORDER_ID_QUEUE, num);
    }
  }

  //  @Autowired
  private RedisQueue3<String> redisQueue3;

  @Test
  public void test7() throws InterruptedException {

    for (int i = 0; i < 100; i++) {
      redisQueue3.pushToHead("test:app" + i);
    }

    Thread.sleep(150 * 500);
    System.out.println("--------------- Sleep End ------------------");
  }

  @Test
  public void test8() {
    final String redisKey = "queue-list";

    final RedisConnectionFactory connectionFactory = redisTemplate.getConnectionFactory();
    final RedisConnection redisConnection = RedisConnectionUtils.getConnection(connectionFactory);
    final byte[] rawKey = redisTemplate.getKeySerializer().serialize(redisKey);

//    final BoundListOperations listOperations = redisTemplate.boundListOps(redisKey);
//    for (int i = 0; i < 4; i++) {
//      listOperations.leftPush("123456" + i);
//    }
    ListOperations listOperations = redisTemplate.opsForList();
    listOperations.leftPush(redisKey, "123");

    List<byte[]> results = redisConnection.bLPop(0, rawKey);
    if (CollectionUtils.isEmpty(results)) {
      return;
    }
    String res = (String) redisTemplate.getValueSerializer().deserialize(results.get(1));
    System.out.println("res = " + res);
  }
}
